<?php

namespace Apps\Weixin\Services;


use Apps\Common\Constant\CacheTimeoutConstant;
use Apps\Common\Service\BaseService;
use Deyi\Functions\HttpFunction;

class WxHelperService extends BaseService
{
    public function getMessageTemplateList($appId)
    {
        $res = $this->getMethodCache($appId);

        if ($res) {
            return $res;
        }

        $url = 'https://api.weixin.qq.com/cgi-bin/template/get_all_private_template?access_token=' . WxResourceService::getInstance()->getAuthorizerAccessToken($appId);

        $res = HttpFunction::getPage($url);

        $this->setMethodCache($res, CacheTimeoutConstant::LOCAL_CACHE, $appId);

        return $res;
    }

    public function sendMessageByTemplate($appId, $toOpenId, $templateId, $data, $url, $miniProgram = [])
    {

        $api = 'https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=' . WxResourceService::getInstance()->getAuthorizerAccessToken($appId);

        $body = [
            'touser' => $toOpenId,
            'template_id' => $templateId,
            'url' => $url,
            'data' => $data
        ];

        if ($miniProgram) {
            $body['miniprogram'] = $miniProgram;
        }

        $ret = HttpFunction::postDataToUrl($api, json_encode($body));

        if (!$ret || !($json = json_decode($ret)) || ($json->errmsg != 'ok')) {
            return false;
        }

        return $json->msgid;
    }


    public function getSubscribeUserList($appId, $nextOpenId = '')
    {
        $url = sprintf(
            'https://api.weixin.qq.com/cgi-bin/user/get?access_token=%s&next_openid=%s',
            WxResourceService::getInstance()->getAuthorizerAccessToken($appId),
            $nextOpenId
        );

        $ret = HttpFunction::getPage($url);

        $openIds = [
            [],
            ''
        ];

        if (!$ret || !($json = json_decode($ret)) || !isset($json->next_openid)) {
            static::$_logger->error('get user list fail:' . $ret);
            return $openIds;
        }

        if (!$json->count) {
            return $openIds;
        }

        if ($json->total == $json->count) {
            $json->next_openid = '';
        }

        return [$json->data->openid, $json->next_openid];
    }


    public function getUserInfoByOpenId($appId, $openId)
    {
        $extraKey = $appId . '#' . $openId;

        $res = $this->getMethodCache($extraKey);

        if ($res) {
            return $res;
        }

        $url = sprintf(
            'https://api.weixin.qq.com/cgi-bin/user/info?access_token=%s&openid=%s&lang=zh_CN',
            WxResourceService::getInstance()->getAuthorizerAccessToken($appId),
            $openId
        );

        $ret = HttpFunction::getPage($url);

        if (!$ret || !($json = json_decode($ret)) || !isset($json->openid)) {
            static::$_logger->error('get user info fail:' . $ret);
            return false;
        }
        $res = (array)$json;
        $this->setMethodCache($res, CacheTimeoutConstant::LOCAL_MAX_CACHE, $extraKey);
        return $res;
    }

    /**
     * 获取用户信息
     * User: yyxi@vip.deyi.com
     * @param $appId
     * @param $code
     * @return bool|mixed
     */
    public function getWeixinUserInfo($appId, $code)
    {
        $url = sprintf('https://api.weixin.qq.com/sns/oauth2/component/access_token?appid=%s&code=%s&grant_type=authorization_code&component_appid=%s&component_access_token=' . WxResourceService::getInstance()->getComponentAccessToken(),
            $appId, $code, static::$_config->weixin->appid);

        $ret = HttpFunction::getPage($url);

        if (!$ret || !($json = json_decode($ret)) || isset($json->errcode)) {
            static::$_logger->warning('get oauth2 access_token fail:' . $ret);
            return false;
        }

        $accessToken = $json->access_token;
        $openId = $json->openid;

        $json = false;

        $url = sprintf('https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN', $accessToken, $openId);

        $ret = HttpFunction::getPage($url);

        static::$_config->project->debug ? static::$_logger->info('get weixinuser info:' . $ret) : '';

        if (!$ret || !($json = json_decode($ret)) || isset($json->errcode)) {
            static::$_logger->warning('get userinfo fail:' . $ret);
            return false;
        }

        return $json;
    }

    public function getAuthorizerInfo($appId)
    {
        $url = 'https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_info?component_access_token=' . WxResourceService::getInstance()->getComponentAccessToken();

        $ret = HttpFunction::postDataToUrl($url, json_encode([
            'component_appid' => static::$_config->weixin->appid,
            'authorizer_appid' => $appId
        ]));

        if (!$ret || !($json = json_decode($ret)) || !isset($json->authorizer_info)) {
            static::$_logger->error('get authorizer info fail:' . $ret);
            return false;
        }

        return $json->authorizer_info;
    }

    public function consumeCardCode($appId, $cardId, $code)
    {
        $try = 3;
        do {

            $url = 'https://api.weixin.qq.com/card/code/consume?access_token=' . WxResourceService::getInstance()->getAuthorizerAccessToken($appId);

            $ret = HttpFunction::postDataToUrl($url, json_encode([
                'code' => $code,
                'card_id' => $cardId
            ]), 10);

            if (!$ret || !($json = json_decode($ret)) || $json->errcode) {
                static::$_logger->error('consume card code fail:' . $ret . ' code:' . $code);
                sleep(rand(1, 3));
                continue;
            }

            return $json->openid;
        } while (--$try);

        return false;
    }

}